package gin_http

import (
	"embed"
	"fmt"
	"gitee.com/captials-team/ubdframe/src/common/utils"
	"gitee.com/captials-team/ubdframe/src/resource/swagger_ui/rapi_doc"
	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
	swaggerFiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"
	"github.com/swaggo/swag"
	"net/http"
	"path/filepath"
	"strings"
)

// SwaggerOption 支持swagger
type SwaggerOption struct {
	Enable  bool   `json:"enable"`
	Name    string `json:"name"`
	Path    string `json:"path"` //指定路由路径
	Swagger *swag.Spec
}

// SwaggerRouter 注册swagger路由
// 访问地址： http://127.0.0.1:10000/swagger/{{Name}}/doc.json
func (s SwaggerOption) SwaggerRouter(g gin.IRouter) {
	if !s.Enable {
		return
	}

	docs := s.Swagger

	//防止复用情况下相互干扰
	docs.InfoInstanceName += utils.RandLetterFigureCode(6)
	swag.Register(docs.InstanceName(), docs)

	corsConfig := cors.DefaultConfig()
	corsConfig.AllowOrigins = []string{"*"}
	corsConfig.AllowCredentials = true
	corsConfig.AllowHeaders = append(corsConfig.AllowHeaders, "Access-Control-Allow-Origin", "Referer")
	corsConfig.OptionsResponseStatusCode = http.StatusOK

	g.GET(s.SwaggerRouterPrefix()+"/*any",
		cors.New(corsConfig),
		SwaggerWrapHtmlHandle(rapi_doc.StaticFs),
		ginSwagger.WrapHandler(swaggerFiles.Handler, ginSwagger.InstanceName(docs.InstanceName())),
	) //默认样式
}

func (s SwaggerOption) SwaggerRouterPath() string {
	return s.SwaggerRouterPrefix() + "/*any"
}

// SwaggerRouterPrefix swagger路由地址
func (s SwaggerOption) SwaggerRouterPrefix() string {
	if s.Path != "" {
		return s.Path
	}
	if s.Name != "" {
		return fmt.Sprintf("/swagger/%s", s.Name)
	}
	return "/swagger"
}

// SwaggerDocsPath swagger docs访问地址
func (s SwaggerOption) SwaggerDocsPath() string {
	return s.Swagger.Host + s.SwaggerRouterPrefix() + "doc.json"
}

func SwaggerWrapHtmlHandle(fs embed.FS) gin.HandlerFunc {
	return func(ctx *gin.Context) {
		i := strings.LastIndex(ctx.Request.URL.Path, "/")
		if i == -1 {
			return
		}

		path := ctx.Request.URL.Path[i+1:]
		if path == "" {
			ctx.Redirect(http.StatusMovedPermanently, ctx.Request.URL.Path+"/index.html")
			return
		}
		switch filepath.Ext(path) {
		case ".html":
			ctx.Header("Content-Type", "text/html; charset=utf-8")
		case ".css":
			ctx.Header("Content-Type", "text/css; charset=utf-8")
		case ".js":
			ctx.Header("Content-Type", "application/javascript")
		case ".png":
			ctx.Header("Content-Type", "image/png")
		case ".json":
			ctx.Header("Content-Type", "application/json; charset=utf-8")
		}

		if content, err := fs.ReadFile("static/" + path); err == nil {
			_, _ = ctx.Writer.Write([]byte(content))
			ctx.Abort()
			return
		}

	}
}
